# Create your views here.

from django.shortcuts import render, HttpResponse, redirect
import random
from blog.utils import validCode, Myforms
from django.http import JsonResponse
from django.contrib import auth
from blog.models import UserInfo
from blog import models
from django.db.models import Count
from django.db import transaction
from django.contrib.auth.decorators import login_required
import os
from cnblogs import settings
from bs4 import BeautifulSoup
import json
from django.db.models import F


# Create your views here.
def index(request):
    article_list = models.Article.objects.all()
    return render(request, 'index.html', locals())


def login(request):
    if request.method == "POST":
        response = {"user": None, "msg": None}
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        Verification_Code = request.POST.get("valid_code")
        valid_code_str = request.session.get("valid_code_str")
        if Verification_Code.upper() == valid_code_str.upper():
            user = auth.authenticate(username=user, password=pwd)
            if user:
                auth.login(request, user)  # 认证用户的登录状态，全局可用,注册的session
                response["user"] = user.username
            else:
                response["msg"] = "username or password error!"
        else:
            response["msg"] = "valid code error"

        return JsonResponse(response)

    return render(request, 'login.html')


def get_random_color():
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))


def get_valid_code_img(request):
    """
    基于PIL模块动态生成响应状态码图片
    :param request:
    :return:
    """
    img_data = validCode.get_valid_code_img(request)

    return HttpResponse(img_data)


def register(request):
    if request.method == "POST":
        response = {"user": None, "msg": None}
        form = Myforms.UserForm(request.POST)
        if form.is_valid():
            response["user"] = form.cleaned_data.get("user")
            # 生成一条用户记录
            user = form.cleaned_data.get('user')
            pwd = form.cleaned_data.get('pwd')
            email = form.cleaned_data.get("email")
            avatar_obj = request.FILES.get("avatar")
            extra = {}
            if avatar_obj:
                extra["avatar"] = avatar_obj
            blog_obj = models.Blog.objects.create(title="{}的博客".format(user), site_name=user,
                                                  theme="{}.css".format(user))
            user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra,
                                                    blog_id=blog_obj.pk)
        else:
            response["msg"] = form.errors
        return JsonResponse(response)

    form = Myforms.UserForm()
    return render(request, 'register.html', locals())


def logout(request):
    auth.logout(request)
    return redirect('/login')


def get_query_data(request, username):
    user = UserInfo.objects.filter(username=username).first()
    if not user:
        return render(request, "not_found.html")
    blog = user.blog
    cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list(
        "title", 'c')
    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list(
        "title", "c")
    date_list = models.Article.objects.filter(user=user).extra(
        select={"Y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("Y_m_date").annotate(
        c=Count("nid")).values_list("Y_m_date", "c")
    return {"blog": blog, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list}


def get_info(username):
    user = UserInfo.objects.filter(username=username).first()
    blog = user.blog
    cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(
        c=Count("article__title")).values_list(
        "title", 'c')

    # 查询当前站点的每一个标签对应的文章数
    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list(
        "title", "c")

    # 查询当前站点每一个年月的所有文章数
    # 方式一
    date_list = models.Article.objects.filter(user=user).extra(
        select={"Y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("Y_m_date").annotate(
        c=Count("nid")).values_list("Y_m_date", "c")
    return {"cate_list": cate_list, "tag_list": tag_list, "date_list": date_list, "blog": blog, "username": username}


def home_site(request, username, **kwargs):
    """
    个人站点视图
    :param request:
    :return:
    """
    user = UserInfo.objects.filter(username=username).first()
    # 判断用户是否存在
    if not user:
        return render(request, "not_found.html")
    # 当前用户对应的所有文章
    blog = user.blog
    # 基于对象的查询
    if kwargs:
        condition = kwargs.get("condition")
        param = kwargs.get("param")
        if condition == "catgory":
            article_list = models.Article.objects.filter(user=user).filter(category__title=param)
        elif condition == "tag":
            article_list = models.Article.objects.filter(user=user).filter(tags__title=param)
        else:
            year, month = param.split("-")
            article_list = models.Article.objects.filter(user=user).filter(create_time__year=year,
                                                                           create_time__month=month)
    else:
        article_list = models.Article.objects.filter(user=user)
    # article_list = user.article_set.all()
    # 基于双下划线的查询

    # 查询每一个分类的名称以及对应的文章数
    # ret = models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title",'c')
    # 查询当前站点的每一个分类名称以及相应的文章数
    cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list(
        "title", 'c')

    # 查询当前站点的每一个标签对应的文章数
    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list(
        "title", "c")

    # 查询当前站点每一个年月的所有文章数
    # 方式一
    date_list = models.Article.objects.filter(user=user).extra(
        select={"Y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("Y_m_date").annotate(
        c=Count("nid")).values_list("Y_m_date", "c")
    # from django.db.models.functions import TruncMonth
    # date_list = models.Article.objects.annotate(month=TruncMonth("create_time")).values("month").annotate(c= Count("nid")).values_list("month","c")

    return render(request, "home_site.html", locals())


def article_detail(request, username, article_id):
    dic = get_query_data(request, username)
    article_obj = models.Article.objects.filter(pk=article_id).first()
    comment_list = models.Comment.objects.filter(article_id=article_id)

    return render(request, "article_detail.html",
                  {**dic, "article_obj": article_obj, "comment_list": comment_list, "username": username})


def digg(request):
    article_id = request.POST.get("article_id")
    is_up = json.loads(request.POST.get("is_up"))
    user_id = request.user.pk
    obj = models.ArticleUpDown.objects.filter(user_id=user_id, article_id=article_id).first()
    response = {"state": True}
    if not obj:
        models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=is_up)
        queryset = models.Article.objects.filter(pk=article_id)
        if is_up:
            queryset.update(up_count=F("up_count") + 1)
        else:
            queryset.update(down_count=F("down_count") + 1)
    else:
        response["state"] = False
        response["handled"] = obj.is_up

    return JsonResponse(response)


def comment(request):
    article_id = request.POST.get("article_id")
    pid = request.POST.get("pid")
    content = request.POST.get("content")
    user_id = request.user.pk
    article_obj = models.Article.objects.filter(pk=article_id).first()
    with transaction.atomic():
        comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content,
                                                    parent_comment_id=pid)
        models.Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1)

    response = {}
    response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X")
    response["username"] = request.user.username
    response["content"] = content

    # 发送邮件
    from django.core.mail import send_mail
    from cnblogs import settings
    # send_mail(
    #     "您的文章%s新加了一条文章评论"%article_id.title,
    #     content,
    #     settings.EMAIL_HOST_USER,
    #     ["1959505142@qq.com"]
    # )
    import threading
    t = threading.Thread(target=send_mail, args=(
        "您的文章%s新加了一条文章评论" % article_id.title,
        content,
        settings.EMAIL_HOST_USER,
        ["1959505142@qq.com"]
    ))
    t.start()

    return JsonResponse(response)


def get_comment_tree(request):
    article_id = request.POST.get("article_id")
    ret = list(models.Comment.objects.filter(article_id=article_id).order_by("pk").values("pk", "content",
                                                                                          "parent_comment_id"))
    return JsonResponse(ret, safe=False)


def get_tag(request):
    category = request.POST.get("category")
    tag = request.POST.get("tag")
    blog_obj = models.UserInfo.objects.filter(username=request.user).values("blog_id").first()
    blog_id = blog_obj.get("blog_id")
    response = {"category": True, "tag": True}
    if category:
        category_status = models.Category.objects.filter(title=category, blog_id=blog_id)
        if not category_status:
            models.Category.objects.create(title=category, blog_id=blog_id)
        else:
            response["category"] = False

    if tag:
        tag_status = models.Tag.objects.filter(title=tag, blog_id=blog_id)
        if not tag_status:
            models.Tag.objects.create(title=tag, blog_id=blog_id)
        else:
            response["tag"] = False

    return JsonResponse(response)


@login_required
def addarticle(request, username):
    if request.method == "POST":
        title = request.POST.get("title")
        content = request.POST.get("content")
        if not content or not title:
            return HttpResponse("标题或文本框不能为空")
        category = request.POST.get("category")
        tag_1 = request.POST.get("tag")
        blog_obj = models.UserInfo.objects.filter(username=request.user).values("blog_id").first()
        blog_id = blog_obj.get("blog_id")

        # 防止xss攻击,过滤script标签
        soup = BeautifulSoup(content, "html.parser")
        for tag in soup.find_all():
            if tag.name == "script":
                tag.decompose()

        # 构建摘要数据,获取标签字符串的文本前150个符号
        #
        desc = soup.text[0:150] + "..."

        if category:
            category_obj = models.Category.objects.filter(title=category, blog_id=blog_id).first()
            if not category_obj:
                category_obj = models.Category.objects.create(title=category, blog_id=blog_id)
            articl_obj = models.Article.objects.create(title=title, desc=desc, content=str(soup), user=request.user,
                                                       category_id=category_obj.pk)
        else:
            articl_obj = models.Article.objects.create(title=title, desc=desc, content=str(soup), user=request.user)
        if tag_1:
            tag_obj = models.Tag.objects.filter(title=tag_1, blog_id=blog_id).first()
            if not tag_obj:
                tag_obj = models.Tag.objects.create(title=tag_1, blog_id=blog_id)
            articl_obj.tags.add(tag_obj)

    userinfo = get_info(username=username)

    return render(request, "add_article.html", {**userinfo})


def upload(request):
    img = request.FILES.get("upload_img")
    path = os.path.join(settings.MEDIA_ROOT, "add_article_img", img.name)
    with open(path, "wb") as f:
        for line in img:
            f.write(line)

    if request.method == "POST":
        ret = {
            'error': 0,
            'url': "/media/add_article_img/%s" % img.name
        }
        return JsonResponse(ret)
    return HttpResponse("ok")


def manager(request, username):
    userinfo = get_info(username=username)
    user = models.UserInfo.objects.filter(username=username).first()
    article_obj = models.Article.objects.filter(user_id=user.pk)
    return render(request, 'manager.html', {**userinfo, "article_obj": article_obj, "username": username})


def delete(request):
    article_id = request.POST.get("article_id")
    article_obj = models.Article.objects.filter(nid=article_id)
    models.Article2Tag.objects.filter(article_id=article_id).delete()
    article_obj.delete()
    return JsonResponse({"ret_status": True})


def editor(request, username, article_id):
    article = models.Article.objects.filter(nid=article_id).first()
    user = get_info(username=username)
    return render(request, 'editor.html', {**user, "article": article})


def update(request):
    if request.method == "POST":
        title = request.POST.get("title")
        content = request.POST.get("content")
        article_id = request.POST.get("article_id")
        # 防止xss攻击,过滤script标签
        soup = BeautifulSoup(content, "html.parser")
        for tag in soup.find_all():
            if tag.name == "script":
                tag.decompose()
        # 构建摘要数据,获取标签字符串的文本前150个符号
        desc = soup.text[0:150] + "..."
        models.Article.objects.filter(nid=article_id).update(title=title, content=content, desc=desc)
        return JsonResponse({"user": request.user.username})
